{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import holoviews as hv\n",
    "from holoviews import opts\n",
    "from holoviews import streams\n",
    "hv.extension('bokeh')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Declaring data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " In this example we will use the BoxDraw stream to draw ROIs over a set of neural calcium imaging data, and use them to compute and display timeseries of the activity in the regions of interests."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = np.load('../../../assets/twophoton.npz')\n",
    "calcium_array = data['Calcium']\n",
    "ds = hv.Dataset((np.arange(50), np.arange(111), np.arange(62), calcium_array),\n",
    "                ['Time', 'x', 'y'], 'Fluorescence')\n",
    "\n",
    "polys = hv.Polygons([])\n",
    "box_stream = streams.BoxEdit(source=polys)\n",
    "\n",
    "def roi_curves(data):\n",
    "    if not data or not any(len(d) for d in data.values()):\n",
    "        return hv.NdOverlay({0: hv.Curve([], 'Time', 'Fluorescence')})\n",
    "    \n",
    "    curves = {}\n",
    "    data = zip(data['x0'], data['x1'], data['y0'], data['y1'])\n",
    "    for i, (x0, x1, y0, y1) in enumerate(data):\n",
    "        selection = ds.select(x=(x0, x1), y=(y0, y1))\n",
    "        curves[i] = hv.Curve(selection.aggregate('Time', np.mean))\n",
    "    return hv.NdOverlay(curves)\n",
    "\n",
    "hlines = hv.HoloMap({i: hv.VLine(i) for i in range(50)}, 'Time')\n",
    "dmap = hv.DynamicMap(roi_curves, streams=[box_stream])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plot"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To define an ROI, select the 'Box edit' tool and double click to start defining the ROI and double click to finish placing the ROI:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "im = ds.to(hv.Image, ['x', 'y'], dynamic=True)\n",
    "(im * polys + dmap * hlines).opts(\n",
    "    opts.Curve(width=400, framewise=True), \n",
    "    opts.Polygons(fill_alpha=0.2, line_color='white'), \n",
    "    opts.VLine(color='black'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<center><img src=\"https://assets.holoviews.org/gifs/gallery/demos/bokeh/box_draw_roi_editor.gif\" width=1000></center>\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
